//
//  ARWorkCommentCell.swift
//  AquaRaft
//
//  Created by 何启亮 on 2024/4/12.
//

import UIKit
import SnapKit
import AttributedString
import KingfisherWebP
import Kingfisher

// MARK: - Define

/// 样式
/// - note: 这里的样式直接就按照位置来
enum ARWorkDetailPathStyle {
    /// 主页进的详情页
    case index
    /// 发现页进的详情页
    case discover
}

// MARK: CellData

class ARWorkCommentCellData: Equatable {
    
    enum value {
        case audioValue(path: String)
        case textValue(comment: NSAttributedString)
    }
    
    // 数据
    let commentModel: ARCommentModel
    let cellHeight: CGFloat
    let value: ARWorkCommentCellData.value
    
    let style: ARWorkDetailPathStyle
    /// 头像View的高度
    static let avatarHeight =  40.0
    /// 音频空间的高度
    static let audioViewHeight = 28.0
    
    // style不一样，边距都不一样
    
    /// container的margin - 垂直
    let containerVeriMargin: CGFloat
    /// 头像上部的margin
    let avatarTopMargin: CGFloat
    /// 头像与comment内容的spacing
    let avatarCommentSpacing: CGFloat
    /// comment与底部的margin
    let commentBottomMargin: CGFloat
    
    // ==== 音频相关
    var playing: Bool = false {
        didSet {
            if playing == false {
                countDown = duration
            }
        }
    }
    var duration: TimeInterval = 0
    var countDown: TimeInterval = 0
    
    init(commentModel: ARCommentModel, style: ARWorkDetailPathStyle) {
        self.commentModel = commentModel
        self.style = style
        
        /// 评论的宽度
        let commentWidth: CGFloat
        switch style {
        case .index:
            self.containerVeriMargin = 0
            self.avatarTopMargin = 24.0
            self.avatarCommentSpacing = 12.0
            self.commentBottomMargin = 8.0
            
            commentWidth = ARHelper.screenWidth() - 16.0 * 2.0
            break
        case .discover:
            self.containerVeriMargin = 8
            self.avatarTopMargin = 14.0
            self.avatarCommentSpacing = 14.0
            self.commentBottomMargin = 16.0
            
            commentWidth = ARHelper.screenWidth() - 16.0 * 4.0
            break
        }
        
        // 这里主要计算高度
        switch commentModel.commentType {
        case .text:
            var commentTextHeight = 0.0
            if let comment = commentModel.comment {
                let asAttri = ASAttributedString(string: comment,
                    .font(ARHelper.font(12, weight: .regular)),
                    .foreground(UIColor(hexString: "#404040") ?? .black),
                    .paragraph(.alignment(.left), .minimumLineHeight(18), .maximumLineHeight(18))
                )
                let attri = asAttri.value
                commentTextHeight = attri.boundingRect(with: .init(width: commentWidth, height: CGFloat.greatestFiniteMagnitude), context: nil).size.height
                self.value = .textValue(comment: attri)
            } else {
                self.value = .textValue(comment: .init())
            }
            self.cellHeight = self.containerVeriMargin * 2.0 + self.avatarTopMargin + Self.avatarHeight + self.avatarCommentSpacing + commentTextHeight + self.commentBottomMargin
            break
        case .audio:
            // 固定
            self.cellHeight = self.containerVeriMargin * 2.0 + self.avatarTopMargin + Self.avatarHeight + self.avatarCommentSpacing + Self.audioViewHeight + self.commentBottomMargin
            
            if let audioPath = commentModel.audioPath {
                self.value = .audioValue(path: audioPath)
            } else {
                self.value = .audioValue(path: "")
            }
            
            self.duration = commentModel.audioDuration
            self.countDown = self.duration
            
            break
        }
        
    }
    
    // AMRK: -
    
    static func == (lhs: ARWorkCommentCellData, rhs: ARWorkCommentCellData) -> Bool {
        return lhs.commentModel.id == rhs.commentModel.id
    }
    
}

// MARK: -

class ARWorkCommentCell: UITableViewCell {

    // MARK: - Property
    
    private var _celldata: ARWorkCommentCellData?
    var celldData: ARWorkCommentCellData? {
        set {
            self.setCellData(newValue)
        }
        get {
            _celldata
        }
    }
    
    var likeBtnClickedCallback: ((ARWorkCommentCell) -> Void)?
    
    /// 点击音频
    var audioClickedCallback: ((ARWorkCommentCellData) -> Void)?
    
    // MARK: -
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        self.setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - UI
    
    private func setupUI() {
        
        contentView.addSubview(containerView)
        containerView.addSubview(avatarView)
        containerView.addSubview(nicknameLabel)
        containerView.addSubview(likeBtn)
        containerView.addSubview(textCommentLabel)
        containerView.addSubview(audioCommentView)
        containerView.addSubview(separatorLine)
        
        audioCommentView.isHidden = true
        textCommentLabel.isHidden = true
    }
    
    // MARK: - Action
    
    @objc private func likeBtnClicked(_ sender: UIButton) {
        likeBtnClickedCallback?(self)
    }
    
    private func setCellData(_ celldata: ARWorkCommentCellData?) {
        let oldValue = _celldata
        _celldata = celldata
        guard let celldata = celldata else {
            return
        }
        
        avatarView.image = nil
        audioCommentView.isHidden = true
        textCommentLabel.isHidden = true
        
        // 设置值
        if let avatarUrl = celldata.commentModel.author?.trueAvatar {
            avatarView.ar.setImage(avatarUrl)
        }
        nicknameLabel.text = celldata.commentModel.author?.nickname
        likeBtn.isSelected = celldata.commentModel.isLike
        
        switch celldata.value {
        case .audioValue(_):
            audioCommentView.isHidden = false
            
            durationCountDownLabel.text = "\(Int(celldata.countDown))s"
            
            playingAnimateView.isHidden = !celldata.playing
            playingSignView.isHidden = celldata.playing
            
            textCommentLabel.snp.removeConstraints()
            audioCommentView.snp.remakeConstraints { make in
                make.left.equalTo(nicknameLabel)
                make.top.equalTo(nicknameLabel.snp.bottom).offset(24)
                make.height.equalTo(ARWorkCommentCellData.audioViewHeight)
                make.bottom.equalToSuperview().offset(-celldata.commentBottomMargin)
            }
            break
        case .textValue(let comment):
            textCommentLabel.isHidden = false
            textCommentLabel.attributedText = comment
            
            audioCommentView.snp.removeConstraints()
            textCommentLabel.snp.remakeConstraints { make in
                make.left.equalTo(avatarView)
                make.right.equalTo(likeBtn)
                make.top.equalTo(avatarView.snp.bottom).offset(celldata.avatarCommentSpacing)
                make.bottom.equalToSuperview().offset(-celldata.commentBottomMargin)
            }
            break
        }
        
        if let oldValue =  oldValue,
        oldValue.style == celldata.style {
            return
        }
        
        containerView.backgroundColor = (celldata.style == .index) ? .clear : UIColor(hexString: "#F7F8FA")
        containerView.layer.cornerRadius = (celldata.style == .index) ? 0 : 16
        
        // 更新
        containerView.snp.remakeConstraints { make in
            make.top.equalToSuperview().offset(celldata.containerVeriMargin)
            make.bottom.equalToSuperview().offset(-celldata.containerVeriMargin)
            if celldata.style == .index {
                make.left.equalToSuperview()
                make.right.equalToSuperview()
            } else {
                make.left.equalToSuperview().offset(16)
                make.right.equalToSuperview().offset(-16)
            }
        }
    
        avatarView.snp.remakeConstraints { make in
            make.left.equalToSuperview().offset(16)
            make.top.equalToSuperview().offset(celldata.avatarTopMargin)
            make.height.width.equalTo(ARWorkCommentCellData.avatarHeight)
        }
        
        nicknameLabel.snp.remakeConstraints { make in
            make.centerY.equalTo(avatarView)
            make.left.equalTo(avatarView.snp.right).offset(16)
            make.right.equalTo(likeBtn.snp.left).offset(-16)
            make.height.equalTo(18)
        }
        
        likeBtn.snp.remakeConstraints { make in
            make.centerY.equalTo(avatarView)
            make.width.height.equalTo(20)
            make.right.equalToSuperview().offset(-16)
        }
        
        separatorLine.snp.remakeConstraints { make in
            make.left.equalTo(avatarView)
            make.right.equalTo(likeBtn)
            make.bottom.equalToSuperview()
            make.height.equalTo(1)
        }
        
        separatorLine.isHidden = celldata.style == .discover
    }
    
    @objc private func audioClicked(_ sender: UIButton) {
        guard let _celldata = celldData else {
            return
        }
        audioClickedCallback?(_celldata)
    }
    
    // MARK: - Lazy
    
    private lazy var containerView: UIView = {
        let view = UIView()
        view.backgroundColor = .clear
        return view
    }()
    
    private lazy var avatarView: UIImageView = {
        let avatarView = UIImageView()
        avatarView.layer.cornerRadius = ARWorkCommentCellData.avatarHeight * 0.5
        avatarView.layer.masksToBounds = true
        avatarView.backgroundColor = .gray.withAlphaComponent(0.8)
        return avatarView
    }()

    private lazy var nicknameLabel: UILabel = {
        let label = UILabel()
        label.font = ARHelper.font(18, weight: .medium)
        label.textColor = UIColor(hexString: "#404040")
        return label
    }()
    
    private lazy var likeBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(likeBtnClicked(_:)), for: .touchUpInside)
        btn.setImage(.init(named: "common_like_btn_normal"), for: .normal)
        btn.setImage(.init(named: "common_like_btn_selected"), for: .selected)
        return btn
    }()
    
    private lazy var textCommentLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 0
        return label
    }()
    
    private lazy var durationCountDownLabel: UILabel = {
        let label = UILabel()
        label.textColor = .white
        label.font = ARHelper.font(16, weight: .regular)
        return label
    }()
    
    private lazy var separatorLine: UIView = {
        let view = UIView()
        view.backgroundColor = .init(hexString: "#CCCCCC")
        view.isHidden = true
        return view
    }()
    
    private lazy var audioCommentView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(hexString: "#3ABBE9")
        view.layer.cornerRadius = ARWorkCommentCellData.audioViewHeight * 0.5
        
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: #selector(audioClicked(_:)), for: .touchUpInside)
        
        view.addSubview(btn)
        view.addSubview(playingSignView)
        view.addSubview(durationCountDownLabel)
        view.addSubview(playingAnimateView)
        
        btn.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        playingSignView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.left.equalToSuperview().offset(20)
            make.width.equalTo(12)
            make.height.equalTo(18)
        }
        playingAnimateView.snp.makeConstraints { make in
            make.center.equalTo(playingSignView)
            make.width.equalTo(12)
            make.height.equalTo(16)
        }
        
        durationCountDownLabel.snp.makeConstraints { make in
            make.left.equalTo(playingSignView.snp.right).offset(8)
            make.right.equalToSuperview().offset(-18)
            make.centerY.equalToSuperview()
        }
        
        return view
    }()
    
    private lazy var playingSignView: UIImageView = {
        let signView = UIImageView(image: .init(named: "post_detail_audio_comment_icon"))
        return signView
    }()
    
    private lazy var playingAnimateView: UIImageView = {
        let view = UIImageView()
        let url = URL(fileURLWithPath: Bundle.main.path(forResource: "audioPlaying_white", ofType: "webp")!)
        view.kf.setImage(with: url, options: [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)])
        view.isHidden = true
        return view
    }()
}
